package com.johnny.connector;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import com.johnny.action.ActionDispatch;
import com.johnny.data.DataPool;
import com.johnny.data.PlayerInfo;
import com.johnny.data.RoomInfo;

public class ConnectorThread extends Thread {
	private List<Socket> socketList = new ArrayList<>();
	private Map<Socket, PlayerInfo> socketPlayerMap = new HashMap<>();
	private int sleepTime;

	public ConnectorThread(int sleepTime) {
		this.sleepTime = sleepTime;
	}

	@Override
	public void run() {
		while (true) {

			synchronized (socketList) {
				for (int i = 0; i < socketList.size(); i++) {
					Socket socket = socketList.get(i);
					try {
						InputStream is = socket.getInputStream();
						if (is.available() > 0) {
							byte[] buffer = new byte[is.available()];
							is.read(buffer);
							System.out.println("<=====================" + new String(buffer));
							String result = ActionDispatch.Dispatch(new String(buffer), socket);
							if (result != null) {
								OutputStreamWriter osWriter=new OutputStreamWriter(socket.getOutputStream());
								osWriter.write(result);
								osWriter.write("\r\n");
								osWriter.flush();
								System.out.println(new String(result) + "===================>");
							}
						}
					} catch (IOException e1) {
						JSONObject object = new JSONObject();
						object.put("action", "Logout");
						ActionDispatch.Dispatch(object.toString(), socket);
						socketPlayerMap.remove(socket);
						socketList.remove(i);
						i--;
						e1.printStackTrace();
					}

					try {
						sleep(sleepTime);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}

			try {
				sleep(sleepTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public void addSocket(Socket socket) {
		synchronized (socketList) {
			socketList.add(socket);
			socketPlayerMap.put(socket, null);
		}

	}

	public PlayerInfo getPlayerInfo(Socket socket) {
		return socketPlayerMap.get(socket);
	}

	public boolean isInThisThread(Socket socket) {
		if (socketPlayerMap.containsKey(socket))
			return true;
		else
			return false;
	}

	public void bindPlayerInfo(Socket socket, PlayerInfo playerInfo) {
		synchronized (socketPlayerMap) {
			socketPlayerMap.remove(socket);
			socketPlayerMap.put(socket, playerInfo);
		}
	}

	public void broadcast(String str) {
		synchronized (socketList) {
			for (int i = 0; i < socketList.size(); i++) {
				Socket socket = socketList.get(i);
				if (socketPlayerMap.get(socket) != null) {
					try {
						OutputStreamWriter osWriter=new OutputStreamWriter(socket.getOutputStream());
						osWriter.write(str);
						osWriter.write("\r\n");
						osWriter.flush();
					} catch (IOException e) {
						JSONObject object = new JSONObject();
						object.put("action", "Logout");
						ActionDispatch.Dispatch(object.toString(), socket);
						socketPlayerMap.remove(socket);
						socketList.remove(i);
						i--;
					}
				}
				try {
					sleep(sleepTime);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

	}
	
	public boolean isPlayerOnline(PlayerInfo player){
		return socketPlayerMap.containsValue(player);
	}

	public void broadcast(String str, String roomId) {
		synchronized (socketList) {
			RoomInfo room = null;
			for (RoomInfo roomInfo : DataPool.getInstance().getRoomInfos()) {
				if (roomInfo.getRoomId().equals(roomId)) {
					room = roomInfo;
					break;
				}
			}
			for (int i = 0; i < socketList.size(); i++) {
				Socket socket = socketList.get(i);
				if (socketPlayerMap.get(socket) != null) {
					try {
						PlayerInfo player = socketPlayerMap.get(socket);
						if (room.getPlayers().contains(player.getName())) {
							OutputStreamWriter osWriter=new OutputStreamWriter(socket.getOutputStream());
							osWriter.write(str);
							osWriter.write("\r\n");
							osWriter.flush();
						}
					} catch (IOException e) {
						JSONObject object = new JSONObject();
						object.put("action", "Logout");
						ActionDispatch.Dispatch(object.toString(), socket);
						socketPlayerMap.remove(socket);
						socketList.remove(i);
						i--;
					}
				}
				try {
					sleep(sleepTime);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

	}
}
